package strongholdCraft.common.core;

import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
import java.util.logging.Level;

import net.minecraftforge.common.Configuration;
import scala.Int;
import strongholdCraft.common.mod_StrongholdCraft;
import strongholdCraft.common.configuration.ConfigurationHandler;
import strongholdCraft.common.configuration.ConfigurationSettings;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.registry.LanguageRegistry;

public class UpdateHandler implements Runnable {
    private static UpdateHandler instance = new UpdateHandler();
	public static String latestVersion = "[VERSION NOT FOUND]";
	public final static String REMOTE_VERSION_XML_FILE = "https://stronghold-craft.googlecode.com/hg/VersionCheck/RemoteVersion.xml";

	 
	    // All possible results of the remote version number check
	    public static final byte UNINITIALIZED = 0;
	    public static final byte CURRENT = 1;
	    public static final byte OUTDATED = 2;
	    public static final byte ERROR = 3;
	    public static final byte FINAL_ERROR = 4;
	    public static final byte MC_VERSION_NOT_FOUND = 5;

	    // Var to hold the result of the remote version check, initially set to uninitialized
	    private static byte result = UNINITIALIZED;
	    public static String remoteVersion = null;
	    public static String remoteUpdateLocation = null;	
	    public static Properties remoteVersionProperties = new Properties();

	
	public static void checkVersion(){
		InputStream remoteVersionRepoStream = null;
        result = UNINITIALIZED;
       
        try {
            URL remoteVersionURL = new URL(REMOTE_VERSION_XML_FILE);
            remoteVersionRepoStream = remoteVersionURL.openStream();
            remoteVersionProperties.loadFromXML(remoteVersionRepoStream);

            String remoteVersionProperty = remoteVersionProperties.getProperty(Loader.instance().getMCVersionString());

            if (remoteVersionProperty != null) {
                String[] remoteVersionTokens = remoteVersionProperty.split("\\|");

                if (remoteVersionTokens.length >= 2) {
                    remoteVersion = remoteVersionTokens[0];
                    remoteUpdateLocation = remoteVersionTokens[1];
                }
                else {
                    result = ERROR;
                }

                if (remoteVersion != null) {
                    if (!ConfigurationSettings.LAST_DISCOVERED_VERSION.equalsIgnoreCase(remoteVersion)) {
                        ConfigurationHandler.set(Configuration.CATEGORY_GENERAL, ConfigurationSettings.LAST_DISCOVERED_VERSION_CONFIGNAME, remoteVersion);
                    }

                   if (remoteVersion.equalsIgnoreCase(getVersionForCheck())) {
                       result = CURRENT;
                  }
                    else {
                        result = OUTDATED;
                    }
                }

            }
            else {
                result = MC_VERSION_NOT_FOUND;
            }
        }
        catch (Exception e) {
        }
        finally {
            if (result == UNINITIALIZED) {
                result = ERROR;
            }

            try {
                if (remoteVersionRepoStream != null) {
                    remoteVersionRepoStream.close();
                }
            }
            catch (Exception ex) {
            }
        }
    }
	
	
	 private static String getVersionForCheck() {

	        String[] versionTokens = Reference.VERSION_NUMBER.split(" ");

	        if (versionTokens.length >= 1)
	            return versionTokens[0];
	        else
	            return Reference.VERSION_NUMBER;
	    }

	    public static void logResult() {

	        if (result == CURRENT || result == OUTDATED) {
	            LogHelper.log(Level.INFO, getResultMessage());
	        }
	        else {
	            LogHelper.log(Level.WARNING, getResultMessage());
	        }
	    }

	    public static String getResultMessage() {

	        if (result == UNINITIALIZED)
	            return Strings.UNINITIALIZED_MESSAGE;
	        else if (result == CURRENT) {
	            String returnString = Strings.CURRENT_MESSAGE;
	            returnString = returnString.replace("@REMOTE_MOD_VERSION@", remoteVersion);
	            returnString = returnString.replace("@MINECRAFT_VERSION@", Loader.instance().getMCVersionString());
	            return returnString;
	        }
	        else if (result == OUTDATED && remoteVersion != null && remoteUpdateLocation != null) {
	            String returnString = Strings.OUTDATED_MESSAGE;
	            returnString = returnString.replace("@MOD_NAME@", Reference.MOD_NAME);
	            returnString = returnString.replace("@REMOTE_MOD_VERSION@", remoteVersion);
	            returnString = returnString.replace("@MINECRAFT_VERSION@", Loader.instance().getMCVersionString());
	            returnString = returnString.replace("@MOD_UPDATE_LOCATION@", remoteUpdateLocation);
	            return returnString;
	        }
	        else if (result == OUTDATED && remoteVersion != null && remoteUpdateLocation != null) {
	            String returnString = Strings.OUTDATED_MESSAGE;
	            returnString = returnString.replace("@MOD_NAME@", Reference.MOD_NAME);
	            returnString = returnString.replace("@REMOTE_MOD_VERSION@", remoteVersion);
	            returnString = returnString.replace("@MINECRAFT_VERSION@", Loader.instance().getMCVersionString());
	            returnString = returnString.replace("@MOD_UPDATE_LOCATION@", remoteUpdateLocation);
	            return returnString;
	        }
	        else if (result == ERROR)
	            return Strings.GENERAL_ERROR_MESSAGE;
	        else if (result == FINAL_ERROR)
	            return Strings.FINAL_ERROR_MESSAGE;
	        else if (result == MC_VERSION_NOT_FOUND) {
	            String returnString =Strings.MC_VERSION_NOT_FOUND;
	            returnString = returnString.replace("@MOD_NAME@", Reference.MOD_NAME);
	            returnString = returnString.replace("@MINECRAFT_VERSION@", Loader.instance().getMCVersionString());
	            returnString = returnString.replace("@ATTEMPTS@", Integer.toString(Reference.VERSION_CHECK_ATTEMPTS));
	            return returnString;
	        }
	        else {
	            result = ERROR;
	            return Strings.GENERAL_ERROR_MESSAGE;
	        }
	    }

	    public static String getResultMessageForClient() {

	        String returnString = Strings.OUTDATED_MESSAGE;
	        returnString = returnString.replace("@MOD_NAME@", Colors.TEXT_COLOUR_PREFIX_YELLOW + Reference.MOD_NAME + Colors.TEXT_COLOUR_PREFIX_WHITE);
	        returnString = returnString.replace("@REMOTE_MOD_VERSION@", Colors.TEXT_COLOUR_PREFIX_YELLOW + UpdateHandler.remoteVersion + Colors.TEXT_COLOUR_PREFIX_WHITE);
	        returnString = returnString.replace("@MINECRAFT_VERSION@", Colors.TEXT_COLOUR_PREFIX_YELLOW + Loader.instance().getMCVersionString() + Colors.TEXT_COLOUR_PREFIX_WHITE);
	        returnString = returnString.replace("@MOD_UPDATE_LOCATION@", Colors.TEXT_COLOUR_PREFIX_YELLOW + UpdateHandler.remoteUpdateLocation + Colors.TEXT_COLOUR_PREFIX_WHITE);
	        return returnString;
	    }

	    public static byte getResult() {

	        return result;
	    }

	    @Override
	    public void run() {

	        int count = 0;

	        LogHelper.log(Level.INFO, Strings.VERSION_CHECK_INIT_LOG_MESSAGE + " " + REMOTE_VERSION_XML_FILE);

	        try {
	            while (count < Reference.VERSION_CHECK_ATTEMPTS - 1 && (result == UNINITIALIZED || result == ERROR)) {

	                checkVersion();
	                count++;
	                logResult();

	                if (result == UNINITIALIZED || result == ERROR) {
	                    Thread.sleep(10000);
	                }
	            }

	            if (result == ERROR) {
	                result = FINAL_ERROR;
	                logResult();
	            }
	        }
	        catch (InterruptedException e) {
	        }

	    }

	    public static void execute() {

	        new Thread(instance).start();
	    }

	}